/*
 * Cell.h
 *
 *  Created on: Apr 24, 2017
 *      Author: zhangjf
 */

#ifndef SRC_CELLSUBSYSTEM_CELL_H_
#define SRC_CELLSUBSYSTEM_CELL_H_

#include <Poco/AutoPtr.h>
#include <Poco/Dynamic/Var.h>
#include <Poco/Task.h>
#include <Poco/BasicEvent.h>
#include <Poco/NotificationQueue.h>
#include <map>

using namespace Poco;
using namespace Poco::Dynamic;
using namespace std;

#include "CellSubsystem.h"
#include "NcsObject.h"

using namespace util;

namespace cell
{

// Cell life cycle status
// Cell must be in one status
typedef enum
{
	CREATING,
	INITIALIZING,
	RUNNING,
	PAUSING,
	DESTROYING
} CELL_RUNNING_STATUS;

class RunningStatusParams
{
public:
	CELL_RUNNING_STATUS oldStatus;
	CELL_RUNNING_STATUS newStatus;
};

class AppNameChangedParams
{
public:
	std::string oldAppName;
	std::string newAppName;
};

class Cell: public NcsObject
{
public:
	typedef AutoPtr<Cell> Ptr;

	Cell(std::string& cellType, std::string& appType, UInt32 nIID);
	virtual ~Cell() {}
	virtual bool initialize();

	// AppType, CellType and iid cannot be modified after creating cell successful.
	std::string& getCellType() { return _cellType; }
	std::string& getAppType() { return _appType; }
	UInt32 getInstanceID()	{ return _iid; }
	std::string& getAppName() { return _appName; }

	void setAppName(std::string& strName);
	BasicEvent<AppNameChangedParams> doAppNameChanged;

	CELL_RUNNING_STATUS getRunningStatus() const { return _runningStatus; }
	BasicEvent<RunningStatusParams> doRunningStatusChanged;

	virtual void runTask();

	template<typename T>
	T getPropertyValue(std::string strProp);
	template<typename T>
	void setPropertyValue(std::string strProp, T value);

	void enqueueNotification(Notification::Ptr pNotification);
	void postNotificationn(Notification::Ptr pNotifcation);

protected:
	void setRunningStatus(CELL_RUNNING_STATUS status);

	void handleNotification(Notification* pNotif);

private:
//	Cell()
//	: CellBase()
//	, Task("Cell") {}

	template<typename T>
	void recallPropertyValue(std::string& strProp);
	template<typename T>
	void rewritePropertyValue(std::string& strProp, Var& val);

	std::string _cellType;
	std::string _appType;
	std::string _appName;
	UInt32 _iid = 0;
	CELL_RUNNING_STATUS _runningStatus = CELL_RUNNING_STATUS::CREATING;

	std::map<std::string, Var> _mapProperty;
};

} /* namespace cell */

#endif /* SRC_CELLSUBSYSTEM_CELL_H_ */
